<?php
/**
 * Copyright (c) 2006, PORTALIER Julien
 *
 * Licensed under The LGPL License
 * Redistributions of files must retain the above copyright notice.
 *
 * @package      FeatherCMS
 * @subpackage   Discusses
 * @copyright    Copyright (c) 2006, Julien PORTALIER
 * @link         http://julien.portalier.com
 * @license      http://www.opensource.org/licenses/lgpl-license.php The LGPL License
 */

abstract class DiscussesController extends Controller
{
	public $_templates = 'discusses';
	public $moduleClass;
	public $refererClass;
	public $components = array('Locker');
	
	protected $refererUnbind;
	protected $rssFields = '*';
	
	//display
	
	function rss($referer_id='void', $module_id=null)
	{
		$model   = $this->{$this->modelClass};
		$referer = $model->{$this->refererClass};
		
		if (!empty($module_id))
		{
			$module  = $referer->{$this->moduleClass};
			$model->conditions(array("{$referer->name}.{$module->foreignKey}" => $module_id));
			$render = 'module_rss';
		}
		elseif ($referer_id != 'void')
		{
			$model->conditions(array("{$model->name}.{$referer->foreignKey}" => $referer_id));
			$render = 'referer_rss';
		}
		
		if (!$this->acl->inGroup(Config::admins))
		{
			$model->conditions(array(
				"{$this->moduleClass}.published"  => PUBLISH_ONLINE,
				"{$this->refererClass}.published" => PUBLISH_ONLINE,
				"{$this->moduleClass}.created"  => '-! < NOW()',
				"{$this->refererClass}.created" => '-! < NOW()'
			));
		}
		
		if ($this->moduleClass and $this->refererClass)
			$model->join($referer->{$this->moduleClass}, $referer);
		
		$model->order("{$model->name}.created DESC");
		$this->data = $model->findAll($this->rssFields, 50);
		$this->__setChannel($referer_id, $module_id);
		
		$this->layout = 'rss';
		$this->load->helpers('rss');
		
		if (isset($render))
			$this->render($render);
	}
	
	// admin
	
	function create($id='void', $referer_id)
	{
		$ref = $this->__checkAccess(null, 'read', $referer_id);
		
		if (empty($this->data))
			$this->data[$this->refererClass]['id'] = $referer_id;
		else
		{
			// anonymous posting?
			if (!$this->acl->identified)
			{
				// stupid captcha for stupid spam bots
				if (!isset($this->data[$this->modelClass]['user_site_f']) or !empty($this->data[$this->modelClass]['user_site_f']))
					Error::show(403);
				
				// paranoia mode on!
				$this->{$this->modelClass}->paranoia = true;
			}
			
			$this->data[$this->refererClass]['id'] = $referer_id;
			$this->data[$this->modelClass]['member_id'] = $this->acl->id;
			$this->data[$this->modelClass][$this->{$this->modelClass}->{$this->refererClass}->foreignKey] = $referer_id;
			
			// remember anonymous member infos? 
			if (isset($this->data[$this->modelClass]['remember_me']))
			{
				$tmp = array(
					$this->data[$this->modelClass]['user_name'],
					$this->data[$this->modelClass]['user_email'],
					$this->data[$this->modelClass]['user_url']
				);
				Cookies::write('FeatherRememberAnonymous', &$tmp);
			}
			
			if ($this->{$this->modelClass}->save())
			{
				$this->flash(_('Your comment has been added.'),
					$this->__referer()."#comment{$this->{$this->modelClass}->id}");
			}
		}
		
		$this->pageTitle = _('New comment');
	}
	
	function edit($id)
	{
		// is identified member?
		if (!$this->acl->identified)
			$this->acl->permissionDenied();
		
		$model   = $this->{$this->modelClass};
		$referer = $model->{$this->refererClass};
		
		if (!$this->acl->inGroup(Config::admins))
		{
			// is user the comment's author? no -> checks if user has rights on the resource
			if ($this->acl->id != $model->field('member_id', null, -1))
				$this->__checkAccess($id, 'write');
		}
		
		$this->Locker->lock("{$this->modelClass}.$id");
		
		if (empty($this->data))
		{
			$model->recursive = -1;
			$this->data = $model->read();
			
			if (empty($this->data))
				Error::show(404);
		}
		else
		{
			$this->data[$this->modelClass]['id'] = $id;
			
			if ($model->save())
			{
				$this->Locker->unlock();
				$this->flash(_('The comment has been updated.'), $this->__referer()."#comment$id");
			}
		}
		
		$this->pageTitle = _('Comment edition');
	}
	
	function delete($id=null)
	{
		$this->__checkAccess($id, 'delete');
		$this->Locker->lock("{$this->modelClass}.$id");
		
		if ($this->{$this->modelClass}->delete())
		{
			$this->Locker->unlock();
			$this->session->setFlash(_("The comment has been deleted."));
		}
		else {
			$this->session->setFlash(_("Oops, an error occured."));
		}
		$this->redirect(getReferer());
	}
	
	function spam($id)
	{
		$this->__checkAccess($id, 'write');
		$spam = $this->field('spam', $id, -1);
		if ($this->saveField('spam', !$spam))
		{
			$this->session->setFlash($spam ? _("Comment has been marked as spam.") :
				_("Comment is no longer marked as spam."));
		}
		else
			$this->session->setFlash(_('Oops, an error occured.'));
		
		$this->redirect(getReferer());
	}
	
	function troll($id)
	{
		$this->__checkAccess($id, 'write');
		$troll = $this->field('troll', $id, -1);
		if ($this->saveField('troll', !$troll))
		{
			$this->session->setFlash($troll ? _("Comment has been marked as troll.") :
				_("Comment is no longer marked as troll."));
		}
		else
			$this->session->setFlash(_('Oops, an error occured.'));
		
		$this->redirect(getReferer());
	}
	
	function cancel($id)
	{
		$this->Locker->unlock("{$this->modelClass}.$id");
		$this->redirect($this->url($id)."#comment$id");
	}
	
	// internals
	
	protected function __referer()
	{
		return isset($this->params['form']['referer']) ?
			$this->params['form']['referer'] : getReferer();
	}
	
	protected function & __checkAccess($id, $action='write', $referer_id=null)
	{
		$model   = $this->{$this->modelClass};
		$referer = $model->{$this->refererClass};
		
		if (empty($referer_id))
		{
			if (!empty($id))
				$referer_id = $model->field($referer->foreignKey, $id, -1);
			else
				Error::show(404);
		}
		
		if (isset($this->moduleClass))
			$fields = "{$this->moduleClass}.published";
		
		if (!empty($this->refererUnbind))
			$referer->unbind(&$this->refererUnbind);
		$referer->recursive = 0;
		$ref = $referer->read("{$this->moduleClass}.id, $fields, {$this->refererClass}.discuss_allow_com", $referer_id);
		
		if (empty($ref))
			Error::show(404);
		
		if (isset($this->moduleClass))
			$this->acl->checkAccess("{$this->moduleClass}.{$ref[$this->moduleClass]['id']}", $action);
		
		return $ref;
	}
	
	abstract protected function __setChannel($referer_id='void', $module_id=null);
	
	abstract function url($data=null);
}
?>